package org.jeecg.modules.business.outbound.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.modules.basic.customer.service.IBasicCustomerService;
import org.jeecg.modules.basic.material.entity.BasicMaterial;
import org.jeecg.modules.basic.material.service.IBasicMaterialService;
import org.jeecg.modules.basic.warehouseGroup.service.IWmsBasicWarehouseGroupUserService;
import org.jeecg.modules.business.doc.outbound.entity.WmsOutReceipt;
import org.jeecg.modules.business.doc.outbound.entity.WmsOutReceiptMaterial;
import org.jeecg.modules.business.doc.outbound.service.IWmsOutReceiptService;
import org.jeecg.modules.business.outbound.entity.WmsOutReceiptTask;
import org.jeecg.modules.business.outbound.entity.WmsOutReceiptTaskMaterial;
import org.jeecg.modules.business.outbound.entity.dto.ListWmsOutReceiptDTO;
import org.jeecg.modules.business.outbound.entity.dto.ListWmsOutReceiptDetailDTO;
import org.jeecg.modules.business.outbound.entity.vo.*;
import org.jeecg.modules.business.outbound.mapper.WmsOutReceiptTaskMapper;
import org.jeecg.modules.business.outbound.mapper.WmsOutReceiptTaskMaterialMapper;
import org.jeecg.modules.business.outbound.po.WmsVisualCorrespondencePO;
import org.jeecg.modules.business.outbound.service.IWmsOutReceiptTaskMaterialService;
import org.jeecg.modules.business.outbound.service.IWmsOutReceiptTaskService;
import org.jeecg.modules.business.outbound.service.WmsVisualCorrespondenceService;
import org.jeecg.modules.business.outbound.vo.WmsOutReceiptTaskMaterialResponseVO;
import org.jeecg.modules.business.repertory.entity.WmsRepertory;
import org.jeecg.modules.business.repertory.mapper.WmsRepertoryMapper;
import org.jeecg.modules.business.third.service.ISapOperateService;
import org.jeecg.modules.business.warehouse.entity.InspectReport;
import org.jeecg.modules.business.warehouse.entity.InspectResultVO;
import org.jeecg.modules.business.warehouse.entity.InspectStatusEnum;
import org.jeecg.modules.business.warehouse.entity.WmsInReceiptTask;
import org.jeecg.modules.business.warehouse.service.IWmsInReceiptTaskService;
import org.jeecg.modules.dock.constant.SystemConstants;
import org.jeecg.modules.dock.entity.DockDataReceiveRecord;
import org.jeecg.modules.dock.entity.dto.response.IngredientsGetResponseDTO;
import org.jeecg.modules.dock.entity.dto.response.ProductReceptionResponseDTO;
import org.jeecg.modules.dock.entity.dto.response.SellOutboundResponseDTO;
import org.jeecg.modules.dock.entity.vms.request.VMSRequestVO;
import org.jeecg.modules.dock.entity.vms.response.VMSResponseVO;
import org.jeecg.modules.dock.service.VmsDockingRepeaterService;
import org.jeecg.modules.flow.callback.enums.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 出库任务
 * @Author: jeecg-boot
 * @Date: 2023-08-09
 * @Version: V1.0
 */
@Slf4j
@Service
public class WmsOutReceiptTaskServiceImpl extends ServiceImpl<WmsOutReceiptTaskMapper, WmsOutReceiptTask> implements IWmsOutReceiptTaskService {

    @Autowired
    private WmsOutReceiptTaskMapper wmsOutReceiptTaskMapper;
    @Autowired
    private WmsOutReceiptTaskMaterialMapper wmsOutReceiptTaskMaterialMapper;
    @Autowired
    private WmsRepertoryMapper wmsRepertoryMapper;
    @Autowired
    private ISysBaseAPI iSysBaseAPI;
    @Autowired
    private IBasicMaterialService basicMaterialService;

    @Resource
    private IBasicCustomerService customerService;

    @Resource
    private IWmsOutReceiptService wmsOutReceiptService;

    @Lazy
    @Resource
    private ISapOperateService sapOperateService;

    @Resource
    private IWmsInReceiptTaskService wmsInReceiptTaskService;

    @Resource
    private IWmsOutReceiptTaskMaterialService wmsOutReceiptTaskMaterialService;

    @Resource
    private IWmsBasicWarehouseGroupUserService wmsBasicWarehouseGroupUserService;

    @Resource
    private WmsVisualCorrespondenceService visualCorrespondenceService;

    @Resource
    private VmsDockingRepeaterService vmsDockingRepeaterService;

    private final String[] VAL = {"01", "11"};
    private static final String STATUS_OK = "200";


    @Override
    @Transactional(rollbackFor = Exception.class)
    public String saveMain(WmsOutReceiptTask wmsOutReceiptTask, List<WmsOutReceiptTaskMaterial> wmsOutReceiptTaskMaterialList) {
        List<WmsOutReceiptTaskMaterial> fillFieldList = new ArrayList<>();
        for (WmsOutReceiptTaskMaterial taskMaterial : wmsOutReceiptTaskMaterialList) {
            //填充字段
            WmsOutReceiptTaskMaterial newTaskMaterial = new WmsOutReceiptTaskMaterial();
            WmsRepertory wmsRepertory = new WmsRepertory();
            LambdaQueryWrapper<WmsRepertory> queryWrapper = new LambdaQueryWrapper<WmsRepertory>();
            if (StrUtil.equalsAny(wmsOutReceiptTask.getDocumentType(), "C27", "C42", "C51")
                    && StrUtil.isEmpty(taskMaterial.getWmsBasicWarehouseId())
                    && StrUtil.isEmpty(taskMaterial.getSapLocationFactory())) {
                wmsRepertory = null;
            } else {
                if (!StrUtil.isEmpty(taskMaterial.getWmsBasicWarehouseId())) {
                    queryWrapper.eq(WmsRepertory::getWmsBasicWarehouseId, taskMaterial.getWmsBasicWarehouseId());
                }

                if (!StrUtil.isEmpty(taskMaterial.getBatchCode())) {
                    queryWrapper.eq(WmsRepertory::getBatchCode, taskMaterial.getBatchCode());
                    queryWrapper.last("LIMIT 1");
                    wmsRepertory = wmsRepertoryMapper.selectOne(queryWrapper);
                } else if (!StrUtil.isEmpty(taskMaterial.getWmsBasicMaterialId())) {
                    queryWrapper.eq(WmsRepertory::getMaterialId, taskMaterial.getWmsBasicMaterialId());
                    queryWrapper.last("LIMIT 1");
                    wmsRepertory = wmsRepertoryMapper.selectOne(queryWrapper);
                }
            }
            if (!Objects.isNull(wmsRepertory)) {
                //先拷贝即时库存字段
                BeanUtil.copyProperties(wmsRepertory, newTaskMaterial);
                //处理一些字段名不同的字段
                newTaskMaterial.setWmsBasicMaterialId(wmsRepertory.getMaterialId());
                newTaskMaterial.setSteelCoilNumber(wmsRepertory.getSteelCode());
                newTaskMaterial.setUnitAssistId(wmsRepertory.getUnitSub());
                newTaskMaterial.setSpecificationModel(wmsRepertory.getSpecification());
            } else {
                String basicMaterialId = taskMaterial.getWmsBasicMaterialId();
                BasicMaterial basicMaterial = null;
                if (StrUtil.isEmpty(basicMaterialId)) {
                    basicMaterial = basicMaterialService.getByCode(taskMaterial.getMaterialCode());
                    if (!Objects.isNull(basicMaterial)) {
                        basicMaterialId = basicMaterial.getId();
                    }
                }
                if (Objects.isNull(basicMaterial)) {
                    basicMaterial = basicMaterialService.getById(basicMaterialId);
                }
                newTaskMaterial.setWmsBasicMaterialId(basicMaterialId);
                newTaskMaterial.setUnitAssistId(taskMaterial.getUnitAssistId());
                if (!Objects.isNull(basicMaterial)) {
                    BeanUtil.copyProperties(basicMaterial, newTaskMaterial);
                    newTaskMaterial.setSpecificationModel(basicMaterial.getSpecification());
                }
            }
            //再拷贝传过来的值
            BeanUtil.copyProperties(taskMaterial, newTaskMaterial, CopyOptions.create().setIgnoreNullValue(true));
            //设置一些不需要赋值的字段
            newTaskMaterial.setId(null);
            newTaskMaterial.setOutboundStatus(null);
            newTaskMaterial.setUnoutboundQuantityAssist(null);
            newTaskMaterial.setUnoutboundQuantity(null);
            fillFieldList.add(newTaskMaterial);
        }
        //设置过账状态
        TransferStatusEnum transferStatus = getTransferStatusWhenSave(SimpleDocumentTypeEnum.OUT_TASK, wmsOutReceiptTask.getDocumentType());
        wmsOutReceiptTask.setTransferSapStatus(transferStatus.getCode());
        this.save(wmsOutReceiptTask);

        if (!CollectionUtil.isEmpty(fillFieldList)) {
            for (WmsOutReceiptTaskMaterial taskMaterial : fillFieldList) {
                //设置任务序号
                if (StrUtil.isEmpty(taskMaterial.getUpstreamLineNumber())) {
                    taskMaterial.setUpstreamLineNumber(fillFieldList.indexOf(taskMaterial) + 1 + "");
                }
                //外键设置
                taskMaterial.setWmsOutReceiptTaskId(wmsOutReceiptTask.getId());
                taskMaterial.setUnoutboundQuantity(taskMaterial.getPlanQuantity());
                //设置辅单位数据
                if (!Objects.isNull(taskMaterial.getAssistQuantity())) {
                    taskMaterial.setOutboundQuantityAssist(BigDecimal.ZERO);
                    taskMaterial.setUnoutboundQuantityAssist(taskMaterial.getAssistQuantity());
                }
                //设置物料质检信息
                taskMaterial.setInspectStatus(InspectStatusEnum.NOT_INSPECT.getName());
                taskMaterial.setUnInspectCanPush("false");
                taskMaterial.setOutboundQuality("false");
                BasicMaterial material = basicMaterialService.getById(taskMaterial.getWmsBasicMaterialId());
                if (material != null) {
                    String inspect = material.getInspect();
                    if (!StrUtil.isEmpty(inspect)) {
                        if (inspect.contains("4")) {
                            taskMaterial.setOutboundQuality("true");
                            taskMaterial.setInspectStatus(InspectStatusEnum.WAIT_INSPECT.getName());
                        }
                        if (inspect.contains("5")) {
                            taskMaterial.setUnInspectCanPush("true");
                        }
                    }
                }
                //basicMaterialService.updateUsedState(entity.getWmsBasicMaterialId());
            }
            wmsOutReceiptTaskMaterialService.saveBatch(fillFieldList);
        }
        customerService.updateUsed(wmsOutReceiptTask.getCustomer());
        return wmsOutReceiptTask.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMain(WmsOutReceiptTask wmsOutReceiptTask, List<WmsOutReceiptTaskMaterial> wmsOutReceiptTaskMaterialList) {
        wmsOutReceiptTaskMapper.updateById(wmsOutReceiptTask);

        List<WmsOutReceiptTaskMaterial> materials = wmsOutReceiptTaskMaterialMapper.selectList(new LambdaQueryWrapper<WmsOutReceiptTaskMaterial>()
                .eq(WmsOutReceiptTaskMaterial::getWmsOutReceiptTaskId, wmsOutReceiptTask.getId()));
        //1.先删除子表数据
        wmsOutReceiptTaskMaterialMapper.deleteByMainId(wmsOutReceiptTask.getId());

        customerService.updateUsed(wmsOutReceiptTask.getCustomer());
        for (WmsOutReceiptTaskMaterial material : materials) {
            basicMaterialService.updateUsedState(material.getWmsBasicMaterialId());
        }

        //2.子表数据重新插入
        if (wmsOutReceiptTaskMaterialList != null && wmsOutReceiptTaskMaterialList.size() > 0) {
            for (WmsOutReceiptTaskMaterial entity : wmsOutReceiptTaskMaterialList) {
                //设置任务序号
                if (StrUtil.isEmpty(entity.getUpstreamLineNumber())) {
                    entity.setUpstreamLineNumber(wmsOutReceiptTaskMaterialList.indexOf(entity) + 1 + "");
                }
                //外键设置
                entity.setWmsOutReceiptTaskId(wmsOutReceiptTask.getId());
                entity.setUnoutboundQuantity(entity.getPlanQuantity());
                //设置辅单位数据
                if (!Objects.isNull(entity.getAssistQuantity())) {
                    entity.setOutboundQuantityAssist(BigDecimal.ZERO);
                    entity.setUnoutboundQuantityAssist(entity.getAssistQuantity());
                }
                wmsOutReceiptTaskMaterialMapper.insert(entity);
                basicMaterialService.updateUsedState(entity.getWmsBasicMaterialId());
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delMain(String id) {
        List<WmsOutReceiptTaskMaterial> materials = wmsOutReceiptTaskMaterialMapper.selectList(new LambdaQueryWrapper<WmsOutReceiptTaskMaterial>()
                .eq(WmsOutReceiptTaskMaterial::getWmsOutReceiptTaskId, id));
        WmsOutReceiptTask task = wmsOutReceiptTaskMapper.selectById(id);
        wmsOutReceiptTaskMaterialMapper.deleteByMainId(id);
        wmsOutReceiptTaskMapper.deleteById(id);
        for (WmsOutReceiptTaskMaterial material : materials) {
            basicMaterialService.updateUsedState(material.getWmsBasicMaterialId());
        }
        customerService.updateUsed(task.getCustomer());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delBatchMain(Collection<? extends Serializable> idList) {
        List<WmsOutReceiptTask> wmsOutReceiptTaskList = this.listByIds(idList);
        if (!CollectionUtil.isEmpty(wmsOutReceiptTaskList)) {
            boolean anyMatch1 = wmsOutReceiptTaskList.stream().anyMatch(task -> DocumentStatusEnum.COMPLETE.getCode().equals(task.getDocumentStatus()));
            if (anyMatch1) {
                throw new JeecgBootException("存在已完成的任务，无法删除");
            }
            boolean anyMatch2 = wmsOutReceiptTaskList.stream().anyMatch(task -> !OutboundStatusEnum.NOT.getCode().equals(task.getOutboundStatus()));
            if (anyMatch2) {
                throw new JeecgBootException("存在已经出库的任务，无法删除");
            }
            List<String> ids = wmsOutReceiptTaskList.stream().map(WmsOutReceiptTask::getId).collect(Collectors.toList());

            List<WmsOutReceiptTaskMaterial> materials = wmsOutReceiptTaskMaterialMapper.selectList(new LambdaQueryWrapper<WmsOutReceiptTaskMaterial>()
                    .in(WmsOutReceiptTaskMaterial::getWmsOutReceiptTaskId, ids));
            for (Serializable id : idList) {
                wmsOutReceiptTaskMaterialMapper.deleteByMainId(id.toString());
                wmsOutReceiptTaskMapper.deleteById(id);
            }
            for (WmsOutReceiptTaskMaterial material : materials) {
                basicMaterialService.updateUsedState(material.getWmsBasicMaterialId());
            }
            for (WmsOutReceiptTask receiptTask : wmsOutReceiptTaskList) {
                customerService.updateUsed(receiptTask.getCustomer());
            }
        }
    }

    @Override
    public ListWmsOutReceiptDTO listWmsOutReceipt(String wmsOutReceiptId) {
        ListWmsOutReceiptDTO listWmsOutReceiptDTO = wmsOutReceiptTaskMapper.listWmsOutReceipt(wmsOutReceiptId, null);
        if (ObjectUtil.isNotEmpty(listWmsOutReceiptDTO)) {
            List<ListWmsOutReceiptDetailDTO> list = listWmsOutReceiptDTO.getList();
            if (ObjectUtil.isNotEmpty(list)) {
                list.forEach(dto -> {
                    List<DictModel> typeDicts = iSysBaseAPI.getDictItems("outbound_type");
                    typeDicts.forEach(type -> {
                        if (type.getValue().equals(dto.getDocumentType())) {
                            dto.setDocumentType_dictText(type.getText());
                        }
                    });
                    List<DictModel> statusDicts = iSysBaseAPI.getDictItems("document_status");
                    statusDicts.forEach(status -> {
                        if (status.getValue().equals(dto.getDocumentStatus())) {
                            dto.setDocumentStatus_dictText(status.getText());
                        }
                    });
                });
            }
        }
        return listWmsOutReceiptDTO;
    }

    @Override
    public IPage<WmsOutReceiptTaskPageVO> listByPage(IPage<WmsOutReceiptTask> page, WmsOutReceiptTaskQueryVO param) {
        if (ObjectUtil.isNotEmpty(param.getDocumentType())) {
            List<String> documentTypeList = Arrays.asList(StringUtils.split(param.getDocumentType(), ","));
            param.setDocumentTypeList(documentTypeList);
        }
        if (ObjectUtil.isNotEmpty(param.getOutWarehouseId())) {
            List<String> outWarehouseIds = Arrays.asList(StringUtils.split(param.getOutWarehouseId(), ","));
            param.setOutWarehouseIds(outWarehouseIds);
        }
        if (!StrUtil.isEmpty(param.getDocumentStatus())) {
            List<String> documentStatusList = Arrays.asList(StrUtil.split(param.getDocumentStatus(), ","));
            param.setDocumentStatusList(documentStatusList);
        }
        //根据当前用户权限过滤
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        if(Objects.isNull(sysUser)){
            param.setAdminFlag(false);
        }else{
            if(StrUtil.contains(sysUser.getUsername(),"admin")){
                param.setAdminFlag(true);
            }else{
                param.setAdminFlag(false);
            }
        }
        List<String> loginUserWarehouseIdList = wmsBasicWarehouseGroupUserService.getLoginUserWarehouseIdList();
        param.setLoginUserWarehouseIdList(loginUserWarehouseIdList);


        return wmsOutReceiptTaskMapper.getPage(page, param);
    }

    /**
     * 通过出库任务id 获取物料即时库存位置信息
     *
     * @param taskMaterialId
     * @return
     */
    @Override
    public RepertorySimpleVO getMaterialRepertoryInfoByOutId(String taskMaterialId) {
        RepertorySimpleVO repertorySimpleVO = new RepertorySimpleVO();
        WmsOutReceiptTaskMaterial taskMaterial = wmsOutReceiptTaskMaterialMapper.selectById(taskMaterialId);
        if (Objects.isNull(taskMaterial)) {
            return repertorySimpleVO;
        }
        WmsOutReceiptTask outReceiptTask = this.getById(taskMaterial.getWmsOutReceiptTaskId());
        if (Objects.isNull(outReceiptTask)) {
            return repertorySimpleVO;
        }
        if (!Objects.isNull(taskMaterial)) {
            //根据任务物料中的明细查询位置
            List<RepertorySimpleVO> repertoryInfoList = new ArrayList<>();
            String tempBatchCode = taskMaterial.getBatchCode();
            String tempWmsBasicMaterialId = taskMaterial.getWmsBasicMaterialId();
            String tempWarehouseId = taskMaterial.getWmsBasicWarehouseId();
            String sapLocationFactory = taskMaterial.getSapLocationFactory();
            if (StrUtil.equalsAny(outReceiptTask.getDocumentType(), "C27", "C42", "C51")
                    && StrUtil.isEmpty(tempWarehouseId)
                    && StrUtil.isEmpty(sapLocationFactory)) {
                return repertorySimpleVO;
            }
            if (!StrUtil.isEmpty(tempBatchCode)) {
                repertoryInfoList = wmsOutReceiptTaskMapper.getMaterialRepertoryInfo(null, tempBatchCode, taskMaterial.getWmsBasicWarehouseId(), null);
            } else {
                repertoryInfoList = wmsOutReceiptTaskMapper.getMaterialRepertoryInfo(tempWmsBasicMaterialId, null, taskMaterial.getWmsBasicWarehouseId(), taskMaterial.getWmsBasicWarehouseAreaId());
            }
            if (!CollectionUtil.isEmpty(repertoryInfoList)) {
                if (repertoryInfoList.size() > 1) {
                    log.warn("根据批次号、物料编码、仓库查询到多条数据，无法确定即时库存位置{},即将取出第一条",repertoryInfoList);
                    repertorySimpleVO=repertoryInfoList.get(0);
                } else {
                    repertorySimpleVO = repertoryInfoList.get(0);
                }
            }
        }
        return repertorySimpleVO;
    }

    @Override
    public Result getMaterialRepertory(String taskMaterialId) {
        RepertorySimpleVO repertorySimpleVO = new RepertorySimpleVO();
        WmsOutReceiptTaskMaterial taskMaterial = wmsOutReceiptTaskMaterialMapper.selectById(taskMaterialId);
        if (Objects.isNull(taskMaterial)) {
            return Result.ok(repertorySimpleVO);
        }
        WmsOutReceiptTask outReceiptTask = this.getById(taskMaterial.getWmsOutReceiptTaskId());
        if (Objects.isNull(outReceiptTask)) {
            return Result.ok(repertorySimpleVO);
        }
        if (!Objects.isNull(taskMaterial)) {
            //根据任务物料中的明细查询位置
            List<RepertorySimpleVO> repertoryInfoList = new ArrayList<>();
            String tempBatchCode = taskMaterial.getBatchCode();
            String tempWmsBasicMaterialId = taskMaterial.getWmsBasicMaterialId();
            String tempWarehouseId = taskMaterial.getWmsBasicWarehouseId();
            String sapLocationFactory = taskMaterial.getSapLocationFactory();
            if (StrUtil.equalsAny(outReceiptTask.getDocumentType(), "C27", "C42", "C51")
                    && StrUtil.isEmpty(tempWarehouseId)
                    && StrUtil.isEmpty(sapLocationFactory)) {
                return Result.ok(repertorySimpleVO);
            }
            if (!StrUtil.isEmpty(tempBatchCode)) {
                repertoryInfoList = wmsOutReceiptTaskMapper.getMaterialRepertoryInfo(null, tempBatchCode, taskMaterial.getWmsBasicWarehouseId(), null);
            } else {
                repertoryInfoList = wmsOutReceiptTaskMapper.getMaterialRepertoryInfo(tempWmsBasicMaterialId, null, taskMaterial.getWmsBasicWarehouseId(), taskMaterial.getWmsBasicWarehouseAreaId());
            }
            if (!CollectionUtil.isEmpty(repertoryInfoList)) {
                if (repertoryInfoList.size() > 1) {
                    return Result.error(-100, "根据批次号、物料编码、仓库查询到多条数据，无法确定即时库存位置");
                } else {
                    repertorySimpleVO = repertoryInfoList.get(0);
                }
            }
        }
        RepertoryLocationVO repertoryLocationVO = cn.hutool.core.bean.BeanUtil.toBean(repertorySimpleVO, RepertoryLocationVO.class);
        return Result.ok(repertoryLocationVO);
    }

    @Override
    public void outboundInspect(InspectResultVO inspectResultVO) {
        log.info("出库质检-wms接收qms请求{}", inspectResultVO);
        DockDataReceiveRecord record = new DockDataReceiveRecord();
        record.setBusinessCode("out");
        HttpServletRequest httpServletRequest = SpringContextUtils.getHttpServletRequest();
        httpServletRequest.setAttribute(SystemConstants.AttachKey.RECEIVE, record);

        for (InspectReport reportDetail : inspectResultVO.getReportDetails()) {
            WmsOutReceiptTaskMaterial one = wmsOutReceiptTaskMaterialMapper.selectOne(new LambdaQueryWrapper<WmsOutReceiptTaskMaterial>()
                    .eq(WmsOutReceiptTaskMaterial::getBatchCode, reportDetail.getSapBatchCode()));
            if (one == null) {
                log.error("成品号:{} 未找到对应出库物料信息", reportDetail.getSteelCoilNum());
                continue;
            }
            WmsOutReceiptTaskMaterial taskMaterial = new WmsOutReceiptTaskMaterial();
            taskMaterial.setId(one.getId());
            taskMaterial.setInspectResult(reportDetail.getResult());
            taskMaterial.setInspectStatus(InspectStatusEnum.INSPECTED.getName());
            taskMaterial.setInspectionMethod(inspectResultVO.getQualityMethod());
            taskMaterial.setInspectTime(inspectResultVO.getStartTime());
            wmsOutReceiptTaskMaterialMapper.updateById(taskMaterial);
        }

    }

    /**
     * 找出已提交超过24小时的销售出库任务，并警告
     */
    @Override
    public void outboundTaskXSCKWarning() {

        List<WmsOutReceiptTask> taskList = wmsOutReceiptTaskMapper.selectList(new LambdaQueryWrapper<WmsOutReceiptTask>()
                .eq(WmsOutReceiptTask::getOutboundStatus, DocumentStatusEnum.COMMIT.getCode())
        );
        if (CollectionUtil.isEmpty(taskList)) {
            return;
        }
        List<WmsOutReceiptTask> warningList = new ArrayList<>();
        for (WmsOutReceiptTask task : taskList) {
            long betweenTime = DateUtil.between(new Date(), task.getUpdateTime(), DateUnit.HOUR, true);
            if (betweenTime > 24) {
                warningList.add(task);
            }
        }
        if (CollectionUtil.isEmpty(warningList)) {
            return;
        }
        //todo 赵军钉钉提醒
    }

    /**
     * 当保存时获取过账状态
     *
     * @return
     */
    @Override
    public TransferStatusEnum getTransferStatusWhenSave(SimpleDocumentTypeEnum simpleDocumentType, String documentType) {
        //如果没有单据类型
        if (StrUtil.isEmpty(documentType)) {
            return TransferStatusEnum.NOT_NEED;
        }
        NeedTransferDocumentTypeEnum[] documentTypeEnums = NeedTransferDocumentTypeEnum.values();
        ArrayList<NeedTransferDocumentTypeEnum> list = ListUtil.toList(documentTypeEnums);
        List<NeedTransferDocumentTypeEnum> collect = list.stream().filter(o -> o.getCode().equals(documentType)).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(collect)) {
            return TransferStatusEnum.NOT_NEED;
        }
        NeedTransferDocumentTypeEnum needTransferDocumentType = collect.get(0);
        if (Objects.isNull(needTransferDocumentType)) {
            return TransferStatusEnum.NOT_NEED;
        } else {
            if (needTransferDocumentType.getSimpleDocumentType().equals(simpleDocumentType.getCode())) {
                return TransferStatusEnum.NOT_TRANSFER;
            } else {
                return TransferStatusEnum.NOT_NEED;
            }
        }
    }

    /**
     * 更新过账状态
     *
     * @param simpleDocumentType
     * @param taskId
     * @param receiptId
     * @param transferStatus
     */
    @Override
    public void updateTransferStatus(SimpleDocumentTypeEnum simpleDocumentType, String taskId, String receiptId, TransferStatusEnum transferStatus) {

        if (SimpleDocumentTypeEnum.OUT_TASK == simpleDocumentType) {
            if (StrUtil.isEmpty(taskId)) {
                return;
            }
            this.update(new LambdaUpdateWrapper<WmsOutReceiptTask>()
                    .set(WmsOutReceiptTask::getTransferSapStatus, transferStatus.getCode())
                    .eq(WmsOutReceiptTask::getId, taskId)
            );
        } else if (SimpleDocumentTypeEnum.OUT_RECEIPT == simpleDocumentType) {
            if (StrUtil.isEmpty(receiptId)) {
                return;
            }
            wmsOutReceiptService.update(new LambdaUpdateWrapper<WmsOutReceipt>()
                    .set(WmsOutReceipt::getTransferSapStatus, transferStatus.getCode())
                    .eq(WmsOutReceipt::getId, receiptId)
            );
        } else {
            log.error("不支持的类型{}", simpleDocumentType);
        }

    }

    /**
     * 出库任务或者出库单过账
     *
     * @param taskId
     * @param receiptId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<String> outTaskAndReceiptTransfer(String taskId, String receiptId) {
        if (StrUtil.isEmpty(taskId) && StrUtil.isEmpty(receiptId)) {
            throw new JeecgBootException("传值错误");
        }
        if (!StrUtil.isEmpty(taskId)) {
            WmsOutReceiptTask wmsOutReceiptTask = this.getById(taskId);
            if (Objects.isNull(wmsOutReceiptTask)) {
                throw new JeecgBootException("出库任务不存在");
            }
            if (!wmsOutReceiptTask.getDocumentType().equals(NeedTransferDocumentTypeEnum.C27.getCode())) {
                throw new JeecgBootException("出库任务无需过账");
            }
            List<String> errorList = new ArrayList<>();
            //调用第三方接口
            List<SellOutboundResponseDTO> sellOutboundResponseDTOList = new ArrayList<>();
            try {
                sellOutboundResponseDTOList = sapOperateService.outboundByTask(taskId);
            } catch (Exception e) {
                log.error(e.getMessage());
                errorList.add(e.getMessage());
                //更新过账状态 过账失败
                updateTransferStatus(SimpleDocumentTypeEnum.OUT_TASK, taskId, null, TransferStatusEnum.TRANSFER_FAIL);
            }
            if (!CollectionUtil.isEmpty(sellOutboundResponseDTOList)) {
                for (SellOutboundResponseDTO sellOutboundResponseDTO : sellOutboundResponseDTOList) {
                    if ("E".equals(sellOutboundResponseDTO.getResult())) {
                        errorList.add(sellOutboundResponseDTO.getMessage());
                        //更新过账状态 过账失败
                        updateTransferStatus(SimpleDocumentTypeEnum.OUT_TASK, taskId, null, TransferStatusEnum.TRANSFER_FAIL);
                    }
                }
            }
            if (CollectionUtil.isEmpty(errorList)) {
                updateTransferStatus(SimpleDocumentTypeEnum.OUT_TASK, taskId, null, TransferStatusEnum.TRANSFER_SUCCESS);
            }
            return errorList;
        }

        //处理出库单过账
        if (!StrUtil.isEmpty(receiptId)) {
            WmsOutReceipt wmsOutReceipt = wmsOutReceiptService.getById(receiptId);
            if (Objects.isNull(wmsOutReceipt)) {
                throw new JeecgBootException("出库单不存在");
            }
            if (!wmsOutReceipt.getDocumentType().equals(NeedTransferDocumentTypeEnum.C42.getCode())
                    && !wmsOutReceipt.getDocumentType().equals(NeedTransferDocumentTypeEnum.C51.getCode()
            )) {
                throw new JeecgBootException("出库单无需过账");
            }
            List<String> errorList = new ArrayList<>();
            if (wmsOutReceipt.getDocumentType().equals(NeedTransferDocumentTypeEnum.C42.getCode())) {
                List<ProductReceptionResponseDTO> responseList = new ArrayList<>();
                try {
                    responseList = sapOperateService.outboundByOrder(receiptId);
                } catch (Exception e) {
                    errorList.add(e.getMessage());
                    //设置过账状态 过账失败
                    updateTransferStatus(SimpleDocumentTypeEnum.OUT_RECEIPT, null, receiptId, TransferStatusEnum.TRANSFER_FAIL);
                }
                if (!CollectionUtil.isEmpty(responseList)) {
                    for (ProductReceptionResponseDTO responseDTO : responseList) {
                        if ("E".equals(responseDTO.getResult())) {
                            errorList.add(responseDTO.getMessage());
                            //设置过账状态 过账失败
                            updateTransferStatus(SimpleDocumentTypeEnum.OUT_RECEIPT, null, receiptId, TransferStatusEnum.TRANSFER_FAIL);
                        }
                    }
                }
                if (CollectionUtil.isEmpty(errorList)) {
                    //设置过账状态 过账成功
                    updateTransferStatus(SimpleDocumentTypeEnum.OUT_RECEIPT, null, receiptId, TransferStatusEnum.TRANSFER_SUCCESS);
                }


            } else if (wmsOutReceipt.getDocumentType().equals(NeedTransferDocumentTypeEnum.C51.getCode())) {
                List<IngredientsGetResponseDTO> responseList = new ArrayList<>();
                try {
                    responseList = sapOperateService.outboundByOrder(receiptId);
                } catch (Exception e) {
                    errorList.add(e.getMessage());
                    //设置过账状态 过账失败
                    updateTransferStatus(SimpleDocumentTypeEnum.OUT_RECEIPT, null, receiptId, TransferStatusEnum.TRANSFER_FAIL);
                }
                for (IngredientsGetResponseDTO responseDTO : responseList) {
                    if ("E".equals(responseDTO.getResult())) {
                        errorList.add(responseDTO.getMessage());
                        //设置过账状态 过账失败
                        updateTransferStatus(SimpleDocumentTypeEnum.OUT_RECEIPT, null, receiptId, TransferStatusEnum.TRANSFER_FAIL);
                    }
                }
            }
            if (CollectionUtil.isEmpty(errorList)) {
                //设置过账状态 过账成功
                updateTransferStatus(SimpleDocumentTypeEnum.OUT_RECEIPT, null, receiptId, TransferStatusEnum.TRANSFER_SUCCESS);
            }
            return errorList;
        }
        return new ArrayList<>();
    }

    /**
     * 检查物料是否存在在执行中的入库任务中
     *
     * @param checkMaterialVOList
     * @return
     */
    @Override
    public NoticeInTaskVO checkMaterialExistProcessInTask(List<CheckMaterialVO> checkMaterialVOList) {
        List<CheckMaterialVO> existList = new ArrayList<>();
        if (CollectionUtil.isEmpty(checkMaterialVOList)) {
            return null;
        }
        for (CheckMaterialVO checkMaterialVO : checkMaterialVOList) {
            //如果批次号是空的，跳过检查
            if (StrUtil.isEmpty(checkMaterialVO.getBatchCode())) {
                continue;
            }
            //如果在即时库存中有数据，跳过校验
            LambdaQueryWrapper<WmsRepertory> queryWrapper = new LambdaQueryWrapper<WmsRepertory>()
                    .eq(WmsRepertory::getBatchCode, checkMaterialVO.getBatchCode());
            Long existCount = wmsRepertoryMapper.selectCount(queryWrapper);
            if (existCount > 0) {
                continue;
            }
            List<String> inTaskIdList = wmsInReceiptTaskService.getProcessTaskIdByMaterialInfo(null, checkMaterialVO.getBatchCode());
            CheckMaterialVO existMaterialVO = new CheckMaterialVO();
            if (CollectionUtil.isEmpty(inTaskIdList)) {
                continue;
            } else {
                existMaterialVO.setWmsBasicMaterialId(checkMaterialVO.getWmsBasicMaterialId());
                existMaterialVO.setBatchCode(checkMaterialVO.getBatchCode());
                existMaterialVO.setInTaskId(inTaskIdList.get(0));
                existList.add(existMaterialVO);
            }
        }
        if (!CollectionUtil.isEmpty(existList)) {
            CheckMaterialVO materialVO = existList.get(0);
            BasicMaterial basicMaterial = basicMaterialService.getById(materialVO.getWmsBasicMaterialId());
            String materialName = Objects.isNull(basicMaterial) ? null : basicMaterial.getName();
            String materialCode = Objects.isNull(basicMaterial) ? null : basicMaterial.getCode();
            WmsInReceiptTask wmsInReceiptTask = wmsInReceiptTaskService.getById(materialVO.getInTaskId());
            NoticeInTaskVO noticeInTaskVO = new NoticeInTaskVO();
            noticeInTaskVO.setMaterialName(materialName);
            noticeInTaskVO.setMaterialCode(materialCode);
            noticeInTaskVO.setInTaskId(wmsInReceiptTask.getId());
            noticeInTaskVO.setDocumentCode(wmsInReceiptTask.getDocumentCode());
            noticeInTaskVO.setBatchCode(materialVO.getBatchCode());

            //下面是pda需要的值
            noticeInTaskVO.setDocumentStatus(wmsInReceiptTask.getDocumentStatus());
            noticeInTaskVO.setDocumentType(wmsInReceiptTask.getDocumentType());
            noticeInTaskVO.setTaskDate(wmsInReceiptTask.getTaskDate());
            noticeInTaskVO.setProductNumber(null);
            noticeInTaskVO.setOriginalSystemNumber(wmsInReceiptTask.getOriginalSystemNumber());
            noticeInTaskVO.setWarehouseKeeper(wmsInReceiptTask.getWarehouseKeeper());
            noticeInTaskVO.setWarehouseStatus(wmsInReceiptTask.getWarehouseStatus());
            return noticeInTaskVO;
        }
        return null;
    }

    /**
     * 出库任务-物料主表ID查询
     * @param id
     * @param code
     * @param unCompleted
     * @param pdaFilterFlag
     * @return
     */
    @Override
    public List<WmsOutReceiptTaskMaterialResponseVO> queryWmsOutReceiptTaskMaterialListByMainId(String id, String code, Boolean unCompleted, Boolean pdaFilterFlag) {
        List<WmsOutReceiptTaskMaterialResponseVO> list=wmsOutReceiptTaskMaterialService.getListByTaskIdWithLight(id,code,unCompleted,null);
        if(!Objects.isNull(pdaFilterFlag)&&pdaFilterFlag){
            //将在出库单中保存的过滤掉
            List<WmsOutReceiptMaterial> receiptMaterialList=wmsOutReceiptService.getReceiptMaterialByTaskId(id);
            if(!CollectionUtil.isEmpty(receiptMaterialList)){
                Map<String, List<WmsOutReceiptMaterial>> listMap = receiptMaterialList.stream().collect(Collectors.groupingBy(WmsOutReceiptMaterial::getWmsOutReceiptTaskMaterialId));
                //找出出库单中需要过滤的物料数据
                Map<String,BigDecimal> needFilterMap=new HashMap<>(16);
                if(!CollectionUtil.isEmpty(listMap)){
                    listMap.forEach((taskMaterialId,tempList)->{
                        if(!StrUtil.isEmpty(taskMaterialId)){
                            if(!CollectionUtil.isEmpty(tempList)){
                                BigDecimal addResult = tempList.stream().map(o->
                                        Objects.isNull(o.getOutboundQuantity())?BigDecimal.ZERO:o.getOutboundQuantity()
                                ).reduce(BigDecimal.ZERO, BigDecimal::add);
                                needFilterMap.put(taskMaterialId,addResult);
                            }
                        }
                    });
                }
                if(!CollectionUtil.isEmpty(needFilterMap)){
                    list=list.stream().filter(o->{
                        if(needFilterMap.containsKey(o.getId())){
                            BigDecimal addResult = needFilterMap.get(o.getId());
                            if(addResult.compareTo(o.getPlanQuantity())<0){
                                return true;
                            }else{
                                return false;
                            }
                        }else{
                            return true;
                        }
                    }).collect(Collectors.toList());
                }
            }
        }
        return list;
    }

    /**
     * 出库任务-物料主表ID查询（带即时库存）
     * @param pdaTaskMaterialReqVO
     * @return
     */
    @Override
    public List<WmsOutReceiptTaskMaterialResponseVO> pdaQueryTaskMaterialByTaskId(PdaTaskMaterialReqVO pdaTaskMaterialReqVO) {
        String taskId = pdaTaskMaterialReqVO.getId();
        String code = pdaTaskMaterialReqVO.getName();
        Boolean unCompleted = pdaTaskMaterialReqVO.getUnCompleted();
        Boolean pdaFilterFlag = pdaTaskMaterialReqVO.getPdaFilterFlag();
        String batchCode = pdaTaskMaterialReqVO.getBatchCode();
        List<WmsOutReceiptTaskMaterialResponseVO> list=wmsOutReceiptTaskMaterialService.getListByTaskIdWithLight(taskId, code, unCompleted,batchCode);
        if(!Objects.isNull(pdaFilterFlag)&&pdaFilterFlag){
            //将在出库单中保存的过滤掉
            List<WmsOutReceiptMaterial> receiptMaterialList=wmsOutReceiptService.getReceiptMaterialByTaskId(taskId);
            if(!CollectionUtil.isEmpty(receiptMaterialList)){
                Map<String, List<WmsOutReceiptMaterial>> listMap = receiptMaterialList.stream().collect(Collectors.groupingBy(WmsOutReceiptMaterial::getWmsOutReceiptTaskMaterialId));
                //找出出库单中需要过滤的物料数据
                Map<String,BigDecimal> needFilterMap=new HashMap<>(16);
                if(!CollectionUtil.isEmpty(listMap)){
                    listMap.forEach((taskMaterialId,tempList)->{
                        if(!StrUtil.isEmpty(taskMaterialId)){
                            if(!CollectionUtil.isEmpty(tempList)){
                                BigDecimal addResult = tempList.stream().map(o->
                                        Objects.isNull(o.getOutboundQuantity())?BigDecimal.ZERO:o.getOutboundQuantity()
                                ).reduce(BigDecimal.ZERO, BigDecimal::add);
                                needFilterMap.put(taskMaterialId,addResult);
                            }
                        }
                    });
                }
                if(!CollectionUtil.isEmpty(needFilterMap)){
                    list=list.stream().filter(o->{
                        if(needFilterMap.containsKey(o.getId())){
                            BigDecimal addResult = needFilterMap.get(o.getId());
                            if(addResult.compareTo(o.getPlanQuantity())<0){
                                return true;
                            }else{
                                return false;
                            }
                        }else{
                            return true;
                        }
                    }).collect(Collectors.toList());
                }
            }
        }
        if(!CollectionUtil.isEmpty(list)){
            for(WmsOutReceiptTaskMaterialResponseVO responseVO:list){
                RepertorySimpleVO repertorySimpleVO = getMaterialRepertoryInfoByOutId(responseVO.getId());
                responseVO.setWmsBasicWarehouseId(repertorySimpleVO.getWmsBasicWarehouseId());
                responseVO.setWmsBasicWarehouseAreaId(repertorySimpleVO.getWmsBasicWarehouseAreaId());
                responseVO.setWmsBasicWarehouseAreaLocationId(repertorySimpleVO.getWmsBasicWarehouseAreaLocationId());
            }
            List<String> warehouseAreaIdList = pdaTaskMaterialReqVO.getWarehouseAreaIdList();
            //根据传入库区进行筛选
            if(!CollectionUtil.isEmpty(warehouseAreaIdList)){
                list=list.stream().filter(o->CollectionUtil.contains(warehouseAreaIdList,o.getWmsBasicWarehouseAreaId())).collect(Collectors.toList());
            }
        }
        return list;
    }

    @Override
    public Result<Result<String>> pdaSignalTrigger(String id, String saddle) {
        // 查询出库单信息
        WmsOutReceiptTask wmsOutReceiptTask = wmsOutReceiptTaskMapper.selectById(id);
        WmsVisualCorrespondencePO vo = new WmsVisualCorrespondencePO();
        vo.setSite(wmsOutReceiptTask.getSiteCode());
        vo.setSaddle(saddle);
        // 查询视觉识别鞍座信息
        WmsVisualCorrespondencePO one = visualCorrespondenceService.getOne(
                new LambdaQueryWrapper<WmsVisualCorrespondencePO>()
                        .eq(WmsVisualCorrespondencePO::getSite, vo.getSite())
                        .eq(WmsVisualCorrespondencePO::getSaddle, vo.getSaddle())
        );

        Result<String> stringResult = new Result<>();
        // 如果未找到视觉识别鞍座信息，则抛出异常
        if (ObjectUtil.isNull(one)) {
            stringResult.setCode(500);
            stringResult.setResult("未找到对应的视觉识别鞍座信息");
            return Result.ok(stringResult);
        }

        // 处理视觉识别鞍座的站点信息
        VMSRequestVO vmsRequestVO = new VMSRequestVO();
        ArrayList<String> strings = new ArrayList<>();
        strings.add(one.getOtherSite());
        vmsRequestVO.setBaseId(strings);

        // 触发VMS信号
        VMSResponseVO vmsResponseVO = vmsDockingRepeaterService.signalTrigger(vmsRequestVO);

        // 检查状态是否为OK
        if (!STATUS_OK.equals(vmsResponseVO.getStatus())) {
            stringResult.setCode(500);
            stringResult.setResult("未找到对应的视觉识别鞍座信息");
            return Result.ok(stringResult);
        }

        // 将VMS信号结果转换为列表
        List<VMSResponseVO.Detail> reason = vmsResponseVO.getReason();
        if (ObjectUtil.isNotNull(reason)) {
            // 获取第一个鞍座号，并进行校验
            VMSResponseVO.Detail detail = reason.get(0);
            if (!ArrayUtil.contains(VAL, detail.getVal())) {
                stringResult.setCode(500);
                stringResult.setResult("未找到对应的视觉识别鞍座信息");
                return Result.ok(stringResult);
            }
        }
        return Result.OK();
    }
}
